feat(tools-list): check deterministic tools/list ordering on the 2026-07-28 wire - #492
Merged
pcarleton merged 4 commits intoSep 6, 2026
Conversation
…-07-28 wire The 2026-07-28 revision adds to server/tools.mdx: "Servers SHOULD return tools in a deterministic order (i.e., the same ordering across requests when the underlying set of tools has not changed)." Nothing in the suite exercised it. Add a tools-list-deterministic-order check to the existing tools-list scenario. From the 2026-07-28 wire on, the scenario takes two more consecutive tools/list snapshots and compares the three name sequences. Same multiset of names, different order is WARNING (SHOULD). A set that changed between probes is reported as untestable rather than as a violation, because the spec scopes the SHOULD to an unchanged set. Fewer than two tools on every probe is INFO. The check carries source.introducedIn '2026-07-28', written as a literal since that revision is published and dated, so runners drop it on earlier wires. Prove it fails: examples/servers/typescript/tools-list-rotated-order.ts advertises the same four tools and rotates the list by one position per call; a negative.test.ts case asserts WARNING while tools-list itself still passes. Unit tests cover the helper that builds the check. Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01BjeC3sCvfHRpdEPz2x41B2
commit: |
…literal Check ids and introducedIn revisions are written inline everywhere else in src/scenarios (tests pin the literal slug on purpose, since SDK baselines reference it), so drop the two exported constants. Co-Authored-By: Claude <noreply@anthropic.com>
Member
|
Pushed one small commit inlining the check id and the '2026-07-28' literal (check ids and introducedIn are written inline elsewhere in src/scenarios, and the tests already pin the literal slug). No behaviour change. Thanks for the work on thisone. |
pcarleton
enabled auto-merge (squash)
September 6, 2026 20:01
Resolve conflicts with modelcontextprotocol#380 (tools-name-format): keep both the Tool Names description line and the deterministic-order line in tools-list, both test imports, and both negative-test describe blocks.
Member
|
Merged main to resolve the conflicts with #380 (kept both the Tool Names and deterministic-order pieces in tools.ts, tools.test.ts and negative.test.ts); check clean and tools/negative/all-scenarios tests pass. Merging on green. |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Discussion: #491.
Requirement
docs/specification/2026-07-28/server/tools.mdx, "Capabilities", lines 71 to 74:https://modelcontextprotocol.io/specification/2026-07-28/server/tools#capabilities
New in 2026-07-28 (absent from 2025-11-25), introduced by modelcontextprotocol/modelcontextprotocol#2516 (not a SEP, so no
src/seps/row). No scenario exercised it before this PR.What changes
One check added to the existing
tools-listscenario (src/scenarios/server/tools.ts), no new scenario, no change torequirements/*.yaml, nosrc/seps/row since the sentence does not come from a SEP.tools-list-deterministic-orderWARNINGtools/listrequests, from the 2026-07-28 wire on (source.introducedIn: '2026-07-28', a literal since the revision is published and dated)SUCCESSwhen the three name sequences are identical;WARNINGwhen the same multiset of names comes back in a different order (first divergent probe and index inerrorMessage, the three orders indetails.orders); untestable under the #248 policy (Not testable: ...,details.untestable: true, WARNING severity) when the multiset changed between probes, since the spec scopes the SHOULD to an unchanged set;INFOwhen no probe saw two toolsThe helper
buildToolsListDeterministicOrderCheck(snapshots)is exported and unit-tested, followingbuildToolsNameFormatCheck. A failure of a repeatedtools/listrequest is reported as untestable on the new check (viauntestableCheck()) instead of turningtools-listitself red. The neighbouring MUST NOT on connection-invariance is deliberately left out, following #332.Prove it passes and fails
all-scenarios.test.tsalready runstools-listagainst the everything-server on both wires; on 2026-07-28 the new check isSUCCESS.examples/servers/typescript/tools-list-rotated-order.tsspeaks the sessionless 2026-07-28 wire, advertises the same four tools and rotates the list by one position on everytools/list. The newnegative.test.tscase assertsWARNINGontools-list-deterministic-orderandSUCCESSontools-listagainst it.Runs against real SDKs
typescript-sdk
mainas of 2026-09-05 (5119ee7fd779),npm start -- sdk typescript-sdk --mode server --scenario tools-list --spec-version 2026-07-28:python-sdk
mainas of 2026-09-05 (7bb486a10fa6),npm start -- sdk python-sdk --mode server --scenario tools-list --spec-version 2026-07-28:Local CI
npm run checkandnpm run buildpass.npm test: 44 files, 536 passed, 0 failed (524 onmainplus the 12 added here). The three "Unhandled Rejection" entries vitest reports are present onmainbefore this change.Notes for review
SKIPPEDor a retry until the set is stable are the alternatives if you prefer.requirements/2026-07-28.yamlliststools-listas scored and is frozen at scenario granularity, so this check raises the bar for a shipped revision. The requirement is 2026-07-28 text, so I left the file untouched; see tools-list: cover the 2026-07-28 SHOULD on deterministic tools/list ordering #491 for the question, and I will follow whatever you decide.untrackedinsrc/seps/traceability.jsonat the next refresh, for lack of a yaml row.AI disclosure
Per
AI_POLICY.md: this PR, the fixture and the tests were written primarily by Claude Code, pointed at this one SHOULD asAGENTS.mdasks, under my direction. Review replies may be AI-assisted as well.